<template>
  <div class="stream-message-container">
    <!-- 思考过程展示 -->
    <n-collapse-transition
      v-if="showThinking && message.thinking"
      :show="showThinking"
    >
      <div class="ai-thinking-bubble">
        <div class="ai-markdown" v-html="safeMarkdownRender(message.thinking)" />
      </div>
    </n-collapse-transition>
    <div v-if="message.thinking && !showThinking" class="ai-thinking-collapsed" @click="toggleThinking">
      思考过程（点击展开）
    </div>
    
    <!-- AI消息内容 -->
    <div 
      class="ai-message-content"
      :class="{
        'streaming': isStreamingState,
        'completed': message.status === 'completed'
      }"
      :key="`content-${message.id}-${forceRefresh}`"
    >
      <!-- 思考中状态 -->
      <div v-if="shouldShowThinking" class="thinking-indicator">
        <div class="thinking-dots">
          <span></span>
          <span></span>
          <span></span>
        </div>
        <span class="thinking-text">AI正在思考...</span>
      </div>
      
      <!-- AI消息文本内容 -->
      <div 
        v-else-if="hasContent" 
        ref="aiMessageRef"
        class="ai-message-text"
        v-html="cachedMarkdown"
      ></div>
      
      <!-- 流式状态下的空内容处理 -->
      <div 
        v-else-if="isStreamingState && !shouldShowThinking" 
        ref="aiMessageRef"
        class="ai-message-text streaming-empty"
        v-html="cachedMarkdown"
        style="min-height: 1.2em; opacity: 0.8;"
      ></div>
      
      <!-- 空消息状态 -->
      <div v-else-if="message.status === 'completed'" class="empty-message">
        AI没有返回任何内容
      </div>
      
      <!-- 等待响应状态 -->
      <div v-else class="empty-message">
        <span v-if="message.status === 'thinking'">等待AI响应...</span>
        <span v-else>等待响应...</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { NCollapseTransition } from 'naive-ui'
import { ref, computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
import type { ChatMessage } from '../../../types/chat'

const props = defineProps<{
  message: ChatMessage
  safeMarkdownRender: (text: string) => string
  showModelName?: boolean
}>()

// 获取模型存储
// 状态管理
const cachedMarkdown = ref('')
const lastText = ref('')
const aiMessageRef = ref<HTMLElement | null>(null)
const showThinking = ref(false)
// 添加一个强制刷新标记
const forceRefresh = ref(0)

// 计算属性
const isStreamingState = computed(() => {
  return props.message.status === 'streaming' || props.message.isStreaming
})

const hasContent = computed(() => {
  return props.message.content && props.message.content.trim() !== ''
})

// 优化后的思考状态计算逻辑
const shouldShowThinking = computed(() => {
  // 依赖forceRefresh，确保在状态变化时重新计算
  forceRefresh.value
  
  // 只有在状态为thinking且没有内容时才显示思考动画
  // 明确排除streaming状态，确保流式内容能立即显示
  return props.message.status === 'thinking' && !hasContent.value && !isStreamingState.value
})

// 更新markdown缓存
const updateMarkdownCache = async () => {
  const content = props.message.content || ''
  
  // 如果内容没有变化，不需要更新
  if (content === lastText.value && cachedMarkdown.value) {
    return
  }
  
  lastText.value = content
  
  // 如果没有内容，清空缓存
  if (!content.trim()) {
    cachedMarkdown.value = ''
    return
  }
  
  try {
    // 更新markdown缓存
    cachedMarkdown.value = props.safeMarkdownRender(content)
  } catch (error) {
    console.error('[StreamMessage] 更新markdown缓存失败:', error);
    // 如果处理失败，使用原始内容作为fallback
    cachedMarkdown.value = `<div>${content}</div>`
  }
  
  // 等待DOM更新
  await nextTick()
  updateDOM()
}

// 更新DOM
const updateDOM = () => {
  if (!aiMessageRef.value) return
  
  try {
    // 设置innerHTML
    aiMessageRef.value.innerHTML = cachedMarkdown.value
    
    // 处理代码高亮
    if (hasContent.value) {
      // 查找所有代码块
      const codeBlocks = aiMessageRef.value.querySelectorAll('pre code')
      if (codeBlocks.length > 0) {
        codeBlocks.forEach((block) => {
          // 获取语言类名
          const className = block.className
          if (className) {
            // 移除前缀，只保留语言名称
            const language = className.replace('language-', '')
            if (language && (window as any).hljs) {
              // 使用highlight.js高亮代码
              (window as any).hljs.highlightElement(block)
            }
          }
        })
      }
      
      // 处理行内代码
      const inlineCodes = aiMessageRef.value.querySelectorAll('code:not(pre code)')
      if (inlineCodes.length > 0) {
        inlineCodes.forEach((code) => {
          // 为行内代码添加样式
          code.classList.add('inline-code')
        })
      }
    }
    
    // 如果是流式状态，滚动到底部
    if (isStreamingState.value) {
      nextTick(() => {
        // 发送滚动事件，让父组件处理滚动
        const event = new CustomEvent('scroll-to-bottom', { bubbles: true })
        aiMessageRef.value?.dispatchEvent(event)
      })
    }
  } catch (error) {
    console.error('[StreamMessage] 更新DOM失败:', error);
  }
}

// 统一的状态和内容变化处理
const handleMessageChange = async () => {
  // 如果有内容但状态还是thinking，强制更新状态
  if (hasContent.value && props.message.status === 'thinking') {
    // 这里我们不能直接更新状态，因为这是一个展示组件
    // 应该通过事件通知父组件
    const event = new CustomEvent('update-message-status', { 
      bubbles: true,
      detail: {
        messageId: props.message.id,
        status: 'streaming'
      }
    })
    aiMessageRef.value?.dispatchEvent(event)
  }
  
  // 立即更新markdown缓存，不做延迟
  await updateMarkdownCache()
  
  // 如果是流式状态，强制触发UI更新
  if (isStreamingState.value) {
    // 增加强制刷新标记，触发计算属性重新计算
    forceRefresh.value++
    
    // 确保DOM更新
    await nextTick()
  }
}

// 监听消息状态和内容变化
watch(
  [() => props.message.status, () => props.message.content, () => props.message.isStreaming],
  async (newValues, oldValues) => {
    // 检查状态是否从streaming变为completed
    if (oldValues && oldValues[0] === 'streaming' && newValues[0] === 'completed') {
      console.log('[StreamMessage] 状态从streaming变为completed，强制更新UI', {
        messageId: props.message.id,
        oldStatus: oldValues[0],
        newStatus: newValues[0]
      });
      
      // 增加强制刷新标记，触发计算属性重新计算
      forceRefresh.value++
      
      // 强制UI更新，确保状态变化被正确渲染
      await nextTick()
    }
    
    // 如果内容发生变化且是流式状态，立即更新UI
    if (newValues[1] !== oldValues?.[1] && isStreamingState.value) {
      // 增加强制刷新标记，触发计算属性重新计算
      forceRefresh.value++
      
      // 立即更新markdown缓存
      await updateMarkdownCache()
      
      // 确保DOM更新
      await nextTick()
    }
    
    await handleMessageChange()
  },
  { immediate: true, deep: true }
)

const toggleThinking = () => {
  showThinking.value = !showThinking.value
}

// 组件挂载后立即更新缓存
onMounted(async () => {
  // 如果消息已有内容，立即渲染
  if (hasContent.value) {
    await updateMarkdownCache()
  }
  
  // 如果有内容但状态还是thinking，强制更新状态
  if (hasContent.value && props.message.status === 'thinking') {
    const event = new CustomEvent('update-message-status', { 
      bubbles: true,
      detail: {
        messageId: props.message.id,
        status: 'streaming'
      }
    })
    aiMessageRef.value?.dispatchEvent(event)
  }
  
  // 添加全局事件监听器，监听强制内容更新事件
  const handleForceContentUpdate = (event: CustomEvent) => {
    if (event.detail.messageId === props.message.id) {
      console.log('[StreamMessage] 接收到强制内容更新事件', {
        messageId: props.message.id,
        status: event.detail.status
      });
      
      // 如果事件中包含状态信息，更新消息状态
      if (event.detail.status) {
        props.message.status = event.detail.status;
        props.message.isStreaming = event.detail.status === 'streaming';
        
        // 如果状态变为completed，增加强制刷新标记
        if (event.detail.status === 'completed') {
          forceRefresh.value++;
        }
      }
      
      // 如果是流式状态，立即更新内容
      if (event.detail.status === 'streaming' || props.message.isStreaming) {
        // 增加强制刷新标记，触发计算属性重新计算
        forceRefresh.value++;
        
        // 立即更新markdown缓存
        updateMarkdownCache();
      } else {
        // 非流式状态，延迟更新
        nextTick(() => {
          updateMarkdownCache();
        });
      }
    }
  };
  
  // 注册事件监听器
  (window as any).addEventListener('force-content-update', handleForceContentUpdate);
  
  // 保存事件监听器引用，以便在组件卸载时移除
  (window as any).__forceContentUpdateHandler = handleForceContentUpdate;
})

// 组件卸载时清理
onUnmounted(() => {
  // 清理可能的定时器或资源
  cachedMarkdown.value = ''
  lastText.value = ''
  
  // 移除全局事件监听器
  const handler = (window as any).__forceContentUpdateHandler;
  if (handler) {
    window.removeEventListener('force-content-update', handler);
    delete (window as any).__forceContentUpdateHandler;
  }
})
</script>

<style scoped>
.stream-message-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  height: auto;
}

.ai-thinking-bubble {
  background: #e6f7ff;
  border: 1px solid #91caff;
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 8px;
  max-width: 70%;
}

.ai-thinking-collapsed {
  background: #e6f7ff;
  border-radius: 4px;
  padding: 4px 8px;
  margin-bottom: 8px;
  font-size: 12px;
  color: #666;
  cursor: pointer;
}

.ai-message-content {
  width: 100%;
  padding: 0px 5px;
  border-radius: 18px;
  /* background-color: #e6f7ff; */
  color: #0d1114;
  border-bottom-left-radius: 4px;
  position: relative;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  min-height: auto;
  height: auto;
  display: block;
  overflow: visible;
}

.thinking-indicator {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px 0;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 12px;
  margin: 8px 0;
}

.thinking-dots {
  display: flex;
  margin-right: 12px;
}

.thinking-dots span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #4A90E2;
  margin: 0 3px;
  animation: thinking 1.4s infinite ease-in-out both;
}

.thinking-dots span:nth-child(1) {
  animation-delay: -0.32s;
}

.thinking-dots span:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes thinking {
  0%, 80%, 100% {
    transform: scale(0);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

.thinking-text {
  color: #4A90E2;
  font-style: italic;
  font-weight: 500;
  font-size: 14px;
}

/* 流式状态下的空内容处理 */
.streaming-empty {
  min-height: 1.2em;
  opacity: 0.8;
}

.ai-message-text {
  line-height: 1.5;
  width: 100%;
  min-height: auto;
  height: auto;
  overflow: visible;
  white-space: normal;
  word-break: break-word;
  display: block;
}

.empty-message {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0;
  color: #999;
  font-style: italic;
}

/* 修复markdown样式 */
.ai-message-text :deep(h1),
.ai-message-text :deep(h2),
.ai-message-text :deep(h3),
.ai-message-text :deep(h4),
.ai-message-text :deep(h5),
.ai-message-text :deep(h6) {
  margin-top: 16px;
  margin-bottom: 8px;
  font-weight: bold;
}

.ai-message-text :deep(h1) {
  font-size: 1.5em;
}

.ai-message-text :deep(h2) {
  font-size: 1.3em;
}

.ai-message-text :deep(h3) {
  font-size: 1.1em;
}

.ai-message-text :deep(p) {
  margin-bottom: 8px;
}

.ai-message-text :deep(code) {
  background-color: rgba(0, 0, 0, 0.06);
  padding: 2px 4px;
  border-radius: 3px;
  font-family: monospace;
}

.ai-message-text :deep(pre) {
  background-color: rgba(0, 0, 0, 0.06);
  padding: 12px;
  border-radius: 6px;
  overflow-x: auto;
  margin-bottom: 8px;
}

.ai-message-text :deep(pre code) {
  background-color: transparent;
  padding: 0;
}

.ai-message-text :deep(ul),
.ai-message-text :deep(ol) {
  margin-bottom: 8px;
  padding-left: 20px;
}

.ai-message-text :deep(li) {
  margin-bottom: 4px;
}

.ai-message-text :deep(a) {
  color: #007aff;
  text-decoration: none;
}

.ai-message-text :deep(a:hover) {
  text-decoration: underline;
}

.ai-message-text :deep(blockquote) {
  border-left: 4px solid #ddd;
  padding-left: 16px;
  margin: 8px 0;
  color: #666;
}

.ai-message-text :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin-bottom: 8px;
}

.ai-message-text :deep(th),
.ai-message-text :deep(td) {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

.ai-message-text :deep(th) {
  background-color: rgba(0, 0, 0, 0.06);
  font-weight: bold;
}
</style>